#include "mfxdefs.h"
#include "mfxcommon.h"
#include "mfxjpeg.h"
#include "mfxstructures.h"
#include "mfxvideo.h"
#include "mfxvideo++.h"
#include "sample_defs.h"
#include "hw_device.h"
#include "base_allocator.h"

extern "C"{
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libavdevice/avdevice.h>
    #include <libavfilter/avfilter.h>
    #include <libavfilter/buffersrc.h>
    #include <libavfilter/buffersink.h>
    #include <libavutil/avutil.h>
    #include <libavutil/pixfmt.h>
    #include <libswresample/swresample.h>
    #include <libswscale/swscale.h>
    #include <libavutil/imgutils.h>
    #include <libavutil/hwcontext.h>
}
#include <boost/thread.hpp>

extern AVPixelFormat g_format;
enum MemType {
    SYSTEM_MEMORY = 0x00,
    D3D9_MEMORY   = 0x01,
    D3D11_MEMORY  = 0x02,
};

struct mfxDHEncode
{
    MemType memType;
    CHWDevice* hwdev;
    MFXVideoENCODE* pmfxENC;
    MFXVideoSession mfxSession;
    MFXFrameAllocator* pMFXAllocator;

    void* user_data;
    void(*encode)(void* obj, unsigned char* data, int& len);

    mfxBitstream mfxBS;
    mfxSyncPoint mfxEncSyncP;
    mfxEncodeCtrl encCtrl;
    mfxVideoParam mfxEncParams;
    mfxFrameSurface1* pEncSurfaces;
    // HEVC
    mfxExtHEVCParam mExtHEVCParam;
    mfxFrameAllocResponse mEncResponse;
    mfxAllocatorParams* pmfxAllocatorParams;

    AVFrame* frame;
    AVFrame* swframe;
    SwsContext* sws;

    mfxDHEncode()
    {
        MSDK_ZERO_MEMORY(encCtrl);
        MSDK_ZERO_MEMORY(mfxEncParams);
        MSDK_ZERO_MEMORY(mExtHEVCParam);
        MSDK_ZERO_MEMORY(mEncResponse);
        MSDK_ZERO_MEMORY(mfxBS);
        MSDK_ZERO_MEMORY(mfxEncSyncP);

        sws = nullptr;
        frame = nullptr;
        swframe = nullptr;

        user_data = nullptr;
        void(*encode)(void* obj, unsigned char* data, int& len)=nullptr;

        hwdev = nullptr;
        pmfxENC = nullptr;
        pMFXAllocator = nullptr;
        pEncSurfaces = nullptr;
        pmfxAllocatorParams = nullptr;
    }
};